package cn.wolfcode.elasticjob.config;

import cn.wolfcode.elasticjob.job.FileCustomJob;
import cn.wolfcode.elasticjob.job.FileDataflowJob;
import com.dangdang.ddframe.job.api.ElasticJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;

/**
 * 任务调度配置类
 */
@Configuration
public class ElasticJobConfig {
    @Autowired		//注入DataSource
    private DataSource dataSource;

    @Autowired  //注入下文参数2
    private CoordinatorRegistryCenter registryCenter;

    //返回作业配置的方法 参数3 需要
    //同样的 newBuilder的参数不能写死，用方法来传递参数来解决，所以定义了四个形参
    private LiteJobConfiguration createJobConfig(Class<? extends ElasticJob> clazz, //任务类的字节码
                                                 String cron, //cron表达式
                                                 int shrdingTotalCount, //分片个数
                                                 String shardingParamter, //分片参数
                                                 Boolean isDataFlowType //是否是数据流DataflowJob类型的任务
    ) {
        JobCoreConfiguration.Builder builder = JobCoreConfiguration.newBuilder(clazz.getSimpleName(), cron, shrdingTotalCount);
        if (!StringUtils.isEmpty(shardingParamter)) {
            //如果传了分片参数，我们需要设置进去
            builder.shardingItemParameters(shardingParamter);
        }

        //数据流DataflowJob类型的任务需要用到 JobTypeConfiguration 做配置定义
        JobTypeConfiguration jobTypeConfiguration = null;

        //根据不同的；任务累心设置不同的配置对象
        if (isDataFlowType){
            //是DataflowJob数据流类型的任务
            // 定义DataflowJob类型配置
            jobTypeConfiguration = new DataflowJobConfiguration(builder.build(), clazz.getCanonicalName(),true);
        }else {
            //不是DataflowJob数据流类型的任务
            // 定义SIMPLE类型配置
            jobTypeConfiguration = new SimpleJobConfiguration(builder.build(), clazz.getCanonicalName());
        }

        // 定义Lite作业根配置
        //overwrite(true)：如果没有这个配置，分片参数的值将始终是第一次设置的值，不会被覆盖，代码修改没有效果，只能删除配置重新设置；加上即可覆盖
        LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(jobTypeConfiguration).overwrite(true).build();
        return simpleJobRootConfig;
    }
/*

    //返回作业配置的方法 参数3 需要
    //同样的 newBuilder的参数不能写死，用方法来传递参数来解决，所以定义了四个形参
    private LiteJobConfiguration createJobConfig(Class<? extends ElasticJob> clazz, //任务类的字节码
                                                 String cron, //cron表达式
                                                 int shrdingTotalCount, //分片个数
                                                 String shardingParamter //分片参数
    ) {
        JobCoreConfiguration.Builder builder = JobCoreConfiguration.newBuilder(clazz.getSimpleName(), cron, shrdingTotalCount);
        if (!StringUtils.isEmpty(shardingParamter)) {
            //如果传了分片参数，我们需要设置进去
            builder.shardingItemParameters(shardingParamter);
        }

        // 定义作业核心配置
        //参数1：作业名称； 参数2：corn 表达式； 参数3：分片数
        //JobCoreConfiguration simpleCoreConfig = JobCoreConfiguration.newBuilder("demoSimpleJob", "0/3 * * * * ?", 1).build(); //不写死
        JobCoreConfiguration simpleCoreConfig = builder.build(); //把builder提起前的原因是要设置分片的次数
        // 定义SIMPLE类型配置
        //参数1：作业配置； 参数2：任务类的全限定名；
        SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(simpleCoreConfig, clazz.getCanonicalName());
        // 定义Lite作业根配置
        //overwrite(true)：如果没有这个配置，分片参数的值将始终是第一次设置的值，不会被覆盖，代码修改没有效果，只能删除配置重新设置；加上即可覆盖
        LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite(true).build();
        return simpleJobRootConfig;
    }
*/



    /*

    @Bean(initMethod = "init")   // 需要将MyElasticJob对象给注入进来,这里给MyElasticJob创建对象并做初始化
    public SpringJobScheduler initMyElasticJobBean(MyElasticJob myElasticJob) {
        //需要的参数：
        // 参数1ElasticJob类型的参数：myElasticJob是间接继承自ElasticJob的，
        // 参数2：需要注入RegistryCenterConfig的对象
        // 参数3LiteJobConfiguration：内容比较多，封装成一个方法createJobConfig，
        return new SpringJobScheduler(myElasticJob, registryCenter,
                createJobConfig(myElasticJob.getClass(),"0/3 * * * * ?", 1, null));
    }
    */
/*

    @Bean(initMethod = "init")      //一分钟去执行
    public SpringJobScheduler initMyElasticJobBean(FileCustomJob fileCustomJob) {
        return new SpringJobScheduler(fileCustomJob, registryCenter,
                //createJobConfig(fileCustomJob.getClass(),"0 0/1 * * * ?", 1, null));  //不分片的情况
                createJobConfig(fileCustomJob.getClass(),"0 0/1 * * * ?", 4, "0=text,1=image,2=radio,3=vedio"));
    }
*/

    @Bean(initMethod = "init")      //一分钟去执行一次
    public SpringJobScheduler initFileDataflowJobBean(FileDataflowJob fileDataflowJob) {
        //增加任务事件追踪配置
        JobEventConfiguration jobEventConfiguration = new JobEventRdbConfiguration(dataSource);
        return new SpringJobScheduler(fileDataflowJob, registryCenter,
                createJobConfig(fileDataflowJob.getClass(),"0 0/1 * * * ?", 1, null,true),jobEventConfiguration);  //不分片的情况
    }
}